﻿using System.Collections;
using System.Dynamic;
using System.Reflection;

namespace Lib.Common;

/// <summary>
/// 数据转换
/// </summary>
public static class Convert {

    #region "Boolean 布尔值"

    /// <summary>
    /// 转换成 Boolean 类型
    /// </summary>
    public static bool ToBoolean(this object e, bool DefaultValue = false) {
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            var Value = e.ToString();
            if ((string.Compare(Value, "true", true) == 0) || (string.Compare(Value, "1", true) == 0) || (string.Compare(Value, "yes", true) == 0) || (string.Compare(Value, "y", true) == 0)) {
                return true;
            } else {
                if ((string.Compare(Value, "false", true) == 0) || (string.Compare(Value, "0", true) == 0) || (string.Compare(Value, "not", true) == 0) || (string.Compare(Value, "n", true) == 0)) {
                    return false;
                }
                try {
                    return System.Convert.ToBoolean(Value);
                } catch {

                }
            }
        }
        return DefaultValue;
    }

    #endregion

    #region "DateTime 时间日期"

    /// <summary>
    /// 转换成 DateTime? 类型
    /// </summary>
    public static DateTime? ToDateTime(this object e, DateTime? DefaultValue = null) {
        DateTime dt = default;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!DateTime.TryParse(e.ToString(), out dt)) {
                return DefaultValue;
            }
        }
        return new Nullable<DateTime>(dt);
    }

    #endregion

    #region "Decimal 高精度浮点数"

    /// <summary>
    /// 转换成 Decimal 类型(高精度浮点数)
    /// </summary>
    public static decimal ToDecimal(this object e, decimal DefaultValue = 0) {
        decimal Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!decimal.TryParse(e.ToString(), out Result)) {
                Result = DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    #region "Double 双精度浮点数字"

    /// <summary>
    /// 转换成 Double 类型(双精度浮点数字)
    /// </summary>
    public static double ToDouble(this object e, double DefaultValue = 0) {
        double Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!double.TryParse(e.ToString(), out Result)) {
                return DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    #region "Float（Single）单精度浮点数字"

    /// <summary>
    /// 转换成 Float 类型(单精度浮点数字)
    /// </summary>
    public static float ToSingle(this object e, float DefaultValue = 0) {
        float Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!float.TryParse(e.ToString(), out Result)) {
                return DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    #region "Int16（Short）有符号整数"

    /// <summary>
    /// 转换成 Int16 类型
    /// </summary>
    public static short ToInt16(this object e, short DefaultValue = 0) {
        short Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!Int16.TryParse(e.ToString(), out Result)) {
                return DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    #region "Int32（Int） 有符号整数"

    /// <summary>
    /// 转换成 Int32 类型
    /// </summary>
    public static int ToInt32(this object e, int DefaultValue = 0) {
        int Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!int.TryParse(e.ToString(), out Result)) {
                return DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    #region "Int64（Long）有符号整数"

    /// <summary>
    /// 转换成 Int64（Long）类型
    /// </summary>
    public static long ToInt64(this object e, long DefaultValue = 0) {
        long Result = DefaultValue;
        if (!System.Convert.IsDBNull(e) && !object.Equals(e, null)) {
            if (!Int64.TryParse(e.ToString(), out Result)) {
                return DefaultValue;
            }
        }
        return Result;
    }

    #endregion

    /// <summary>
    /// 根据类型名称转换对应 Type 类型
    /// </summary>
    public static Type GetType(string type) {
        return type.ToLower() switch {
            "int" => Type.GetType("System.Int32", true, true),
            "string" => Type.GetType("System.String", true, true),
            "bool" => Type.GetType("System.Boolean", true, true),
            "date" or "datetime" => Type.GetType("System.DateTime", true, true),
            "byte" => Type.GetType("System.Byte", true, true),
            "sbyte" => Type.GetType("System.SByte", true, true),
            "char" => Type.GetType("System.Char", true, true),
            "decimal" => Type.GetType("System.Decimal", true, true),
            "double" => Type.GetType("System.Double", true, true),
            "float" => Type.GetType("System.Single", true, true),
            "uint" => Type.GetType("System.UInt32", true, true),
            "long" => Type.GetType("System.Int64", true, true),
            "ulong" => Type.GetType("System.UInt64", true, true),
            "object" => Type.GetType("System.Object", true, true),
            "short" => Type.GetType("System.Int16", true, true),
            "ushort" => Type.GetType("System.UInt16", true, true),
            "guid" => Type.GetType("System.Guid", true, true),
            _ => Type.GetType(type, true, true),
        };
    }

    /// <summary>
    /// 实体类转字典类型对象
    /// </summary>
    /// <param name="e">对象</param>
    /// <param name="Fields">要转换的字段列表, 如果是要忽略的字段,前端带“@”的是要忽略的属性，如："@,Password,Age"</param>
    /// <param name="IgnoreNullValue">是否忽略空值属性</param>
    public static IDictionary<string, object> ToDictionary(this object e, string Fields = null, bool IgnoreNullValue = false) {
        if (e == null) {
            return null;
        }
        if (e is ExpandoObject) {
            return (IDictionary<string, object>)e;
        }
        var Result = new Dictionary<string, object>();
        var Type = e.GetType();
        var IsProcessed = false;
        var Ignore = false;
        var Index = 0;
        var List = new List<string>();
        if (!string.IsNullOrEmpty(Fields)) {
            IsProcessed = true;
            List = [.. Fields.Split(',')];
            if (Fields.StartsWith('@')) {
                Ignore = true; List.RemoveAt(0);
            }
        }
        foreach (PropertyInfo P in Type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
            if (IsProcessed && ((Ignore && List.Contains(P.Name)) || (!Ignore && !List.Contains(P.Name)))) {
                continue;
            }
            if (!Result.ContainsKey(P.Name)) {
                object Value = P.GetValue(e, null);
                if (Value == null && IgnoreNullValue) {
                    continue;
                }
                Result.Add(P.Name, Value); Index++;
            }
        }
        if (Index == 0) {
            return null;
        }
        return Result;
    }
    /// <summary>
    /// 字典类型对象转实体类
    /// </summary>
    public static T ToEntity<T>(this IDictionary Re, object e = null) where T : class {
        T Result = default;
        if (e != null) {
            Result = (T)e;
        }
        if (Re == null) {
            return Result;
        }
        Type Type = Result.GetType();
        foreach (DictionaryEntry Rs in Re) {
            var Key = Rs.Key.ToString();
            var P = Type.GetProperty(Key);
            if (P == null) {
                var F = Type.GetField(Key);
                if (F == null) {
                    continue;
                } else {
                    F.SetValue(Result, Rs.Value);
                }
            } else {
                P.SetValue(Result, Rs.Value, null);
            }
        }
        return Result;
    }
    /// <summary>
    /// 字符转换成指定枚举
    /// </summary>
    public static T ToEnum<T>(this string Value, T DefaultValue = default) where T : Enum {
        try {
            return (T)Enum.Parse(typeof(T), Value);
        } catch {

        }
        return DefaultValue;
    }
    /// <summary>
    /// 数字换成指定枚举
    /// </summary>
    public static T ToEnum<T>(this int Value, T DefaultValue = default) where T : Enum {
        try {
            return (T)Enum.ToObject(typeof(T), Value);
        } catch {
            return DefaultValue;
        }
    }


}

